home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 6 / cljune86.zip / LERP.ASM < prev    next >
Assembly Source File  |  1986-03-31  |  4KB  |  118 lines

  1. page 58,132
  2. ;    file:    LERP.ASM
  3. ;
  4. ;        LERP stands for Linear intERPolation.
  5. ;    THIS ROUTINE ACCEPTS THREE SHORT INTEGET ARGUMENTS, IT
  6. ;    MULTIPLYS THE FIRST TWO TOGETHER, THEN ADDS HALF OF THE
  7. ;    THIRD ARGUMENT AND DIVIDES BY THE THIRD ARGUMENT.
  8. ;
  9. ;    THE MULTIPLY IS A 16*16 GIVING 32 BITS, AND THE DIVIDE IS
  10. ;    A 32/16 GIVING 16 BIT DIVIDE, SO NO OVERFLOW SHOULD HAPPEN.
  11. ;    ADDING HALF OF THE DIVISOR RESULTS IN THE ANSWER BEING ROUNDED
  12. ;    OFF AT 0.5.  DIVIDING BY ZERO WILL RESULT IN AN ANSWER THAT IS
  13. ;    +/- 32767 -- THE 16BIT INTEGER EQUIVALENT OF INFINITY.
  14. ;
  15. ;   (c) Copyright 1984 by The Computer Entomologist
  16. ;
  17. ;    Permission is hearby granted to use or distribute this software
  18. ;without any restrictions.  You may make copies for yourself or your
  19. ;friends. You may include it in any hardware or software product that you
  20. ;sell for profit.
  21. ;
  22. ;    This software is distributed as is, and is not guaranteed to work
  23. ;on any particular hardware/software configuration.  Furthermore, no 
  24. ;liability is granted with this software: the user takes responcibility for
  25. ;any damage this software may do to his system.
  26. ;
  27. ;    Nasy notices aside, if you have any questions about this software, you
  28. ;can reach me at the address below.  If you impliment any new features or
  29. ;find (and fix!) any bugs, I would be happy to hear from you.
  30. ;
  31. ;    Mike Higgins
  32. ;    The Computer Entomologist
  33. ;    P.O. Box 197
  34. ;    Duncans Mills, CA 95430
  35. ;
  36. ;PARAMETERS:
  37. NUM=6        ;A NUMBER TO BE TRANSFORMED
  38. MULT=8        ;THE AMOUNT TO MULTIPLY BY
  39. DIVIS=10    ;THE AMOUNT TO DIVIDE BY
  40.  
  41. INCLUDE    MODEL.H
  42. INCLUDE    PROLOGUE.H
  43.  
  44.     PUBLIC    LERP
  45. LERP    PROC    FAR
  46.     PUSH    BP    ;DO THE NORMAL STACK FRAMING
  47.     MOV    BP,SP
  48.  
  49.     MOV    AX,NUM[BP]    ;GET THE FIRST ARGUMENT
  50.     XOR    BH,BH            ;BH WILL CONTAIN THE SIGN OF RESULT
  51.     OR    AH,AH            ;TAKE THE ABS OF 1ST ARGUMENT
  52.     JGE    POS1
  53.     MOV    BH,AH            ;SAVE THE SIGN IN BH
  54.     NEG    AX
  55. POS1:
  56.     MOV    CX,MULT[BP]        ;GET THE 2ND ARGUMENT
  57.     OR    CH,CH            ;TAKE IT'S ABSULUTE VALUE
  58.     JGE    POS2
  59.     XOR    BH,CH            ;BUT SAVE SIGN FIRST
  60.     NEG    CX
  61. POS2:
  62.     IMUL    CX            ;MULTIPLY BY THE 2ND ARGUMENT.
  63.     MOV    CX,DIVIS[BP]        ;GET THE THIRD ARGUMENT,
  64.     OR    CX,CX            ;CHECK IT TO SEE IF IT IS
  65.     JG    POS3            ;POSITIVE, OR IF
  66.     JL    NEG3            ;NEGATIVE.
  67. INFINITY:
  68.     MOV    AX,07FFFH        ;IF ZERO, RETURN A LARGE NUMBER
  69.     JMP    SIGN            ;POSITIVE OR NEGATIVE INFINITY)
  70. NEG3:
  71.     XOR    BH,CH            ;SAVE THE SIGN OF DIVISOR,
  72.     NEG    CX            ;AND MAKE IT POSITIVE
  73. POS3:
  74.     IDIV    CX            ;FINALLY, DO THE DIVISION
  75.     SAR    CX,1            ;AND DIVIDE DIVISOR BY 2
  76.     CMP    CX,DX            ;IS REMAINDER >= 1/2 DIVISOR?
  77.     JG    SIGN            ;NO.
  78.     INC    AX            ;YES, INCRIMENT RESULT.
  79. SIGN:    OR    BH,BH            ;CHECK THE SIGN OF THE RESULT
  80.     JGE    DONE            ;IF POSITIVE, YOU CAN QUIT
  81.     NEG    AX            ;ELSE MAKE THE RESULT NEGATIVE NOW
  82. DONE:
  83.     POP    BP
  84.     RET
  85. LERP    ENDP
  86.  
  87. ;
  88. ;        Can you beleive it?  On the 8088/86/286 it is impossible
  89. ;    to test for integer overflow on a divide!  The only way to detect
  90. ;    this error is to catch divide-by-zero interupts!  So I wrote the
  91. ;    following two routines:  OVRSET() must be called once by your main
  92. ;    program, and it points the divide overflow vector at DIVOVR.  This
  93. ;    version of DIVOVR always assumes a 32 by 16 bit divide, and just
  94. ;    loads AX and DX with "infinity" with no remainder.
  95. ;
  96. DIVOVR    PROC    FAR    ;ROUTINE TO PROCESS DIVISION OVERFLOW ERRORS
  97.     MOV    AX,07FFFH    ;CHANGE AX TO A LARGE NUMBER
  98.     XOR    DX,DX        ;ZERO DX (ASSUME 16 BIT DIVIDE)
  99.     IRET            ;AND RETURN, THAT'S ALL.
  100. DIVOVR    ENDP
  101.  
  102.     PUBLIC    OVRSET
  103. OVRSET    PROC    FAR    ;ROUTINE TO SET DIVISION OVERFLOW INTERUPT VECTOR
  104.  
  105.     PUSH    DS
  106.     MOV    AX,CS    ;USE CURRENT CODE SEGMENT
  107.     MOV    DS,AX
  108.     MOV    DX,OFFSET @CODE:DIVOVR
  109.     MOV    AX,02500H    ;ASK TO LOAD THE DIVIDE BY ZERO VECTOR
  110.     INT    21H
  111.     POP    DS
  112.     RET
  113. OVRSET    ENDP
  114.  
  115. INCLUDE EPILOGUE.H
  116.  
  117.     END
  118.